package com.apes.fn.fico.prefetch.service;

import com.apes.fn.fico.prefetch.model.PrefetchExpense;
import com.apes.fn.fico.prefetch.model.PrefetchExpenseItem;
import com.apes.fn.fico.prefetch.model.PrefetchExpenseLedger;
import com.apes.fn.fico.prefetch.repository.PrefetchExpenseLedgerRepository;
import com.apes.fn.fico.prefetch.repository.PrefetchExpenseRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.ReflectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.LinkedHashMap;

/**
 * @Title: PrefetchExpenseService
 * @Description: 预提费用
 * @author: ZhengZeXian
 * @create: 2022/2/15 11:13
 */
@Service("prefetchExpenseService")
public class PrefetchExpenseService extends DomainService {

    @Autowired
    private PrefetchExpenseRepository expenseRepository;
    @Autowired
    private PrefetchExpenseLedgerRepository ledgerRepository;

    static LinkedHashMap<String, String> monthMap = new LinkedHashMap<>(12);
    {
        monthMap.put("january", "01");
        monthMap.put("february", "02");
        monthMap.put("march", "03");
        monthMap.put("april", "04");
        monthMap.put("may", "05");
        monthMap.put("june", "06");
        monthMap.put("july", "07");
        monthMap.put("august", "08");
        monthMap.put("september", "09");
        monthMap.put("october", "10");
        monthMap.put("november", "11");
        monthMap.put("december", "12");
    }
    
    /***
     * 创建
     */
    public PrefetchExpense create(SimpleRequest request) {
        PrefetchExpense PrefetchExpense = request.getO(PrefetchExpense.class);
        PrefetchExpense.setState("create");
        return expenseRepository.saveAndFlush(PrefetchExpense);
    }

    /***
     * 更新
     */
    public PrefetchExpense update(SimpleRequest request) {
        isVaild(request, expenseRepository);
        PrefetchExpense prefetchExpense = request.getO(PrefetchExpense.class);
        return expenseRepository.saveAndFlush(prefetchExpense);
    }

    /***
     * 删除
     */
    public PrefetchExpense delete(SimpleRequest request) {
        isVaild(request, expenseRepository);
        PrefetchExpense prefetchExpense = request.getO(PrefetchExpense.class);
        prefetchExpense.setState("delete");
        return expenseRepository.saveAndFlush(prefetchExpense);
    }

    /**
     * 审核
     */
    public PrefetchExpense approve(SimpleRequest request) {
        isVaild(request, expenseRepository);
        PrefetchExpense prefetchExpense = request.getO(PrefetchExpense.class);
        prefetchExpense.setState("approve");
        prefetchExpense.setApproveId(request.getPerson());
        prefetchExpense.setApproveDate(new Date());

        prefetchExpense.setFiscalYear(DateUtil.getYearFirstDay(prefetchExpense.getFiscalYear()));

        //获取财务年度
        String year = DateUtil.format(prefetchExpense.getFiscalYear(), "YYYY");
        prefetchExpense.getPrefetchExpenseItems().forEach(item -> {
            monthMap.forEach((k,v) -> {
                Double amount = ReflectUtil.getFieldValue(item, k);
                if (amount == 0) return;
                //写入预提费用总账 为0的不写
                writeLedger(item,amount,year+"-"+v);
            });
        });

        return expenseRepository.saveAndFlush(prefetchExpense);
    }

    /**
     * 写入预提费用总账
     * @param item 预提费用明细
     * @param amount 金额
     * @param month 会计年月
     */
    public void writeLedger(PrefetchExpenseItem item,Double amount,String month){
        PrefetchExpenseLedger ledger = new PrefetchExpenseLedger();
        ledger.setPrefetchExpense(item.getPrefetchExpense());
        ledger.setCompany(item.getPrefetchExpense().getCompany());
        ledger.setDutyCenter(item.getDutyCenter());
        ledger.setFiscalYear(item.getPrefetchExpense().getFiscalYear());
        ledger.setFeeType(item.getFeeType());
        ledger.setAmount(amount);
        ledger.setAccountantMonth(DateUtil.parse(month,DateUtil.SHOW_MONTH_FORMAT));
        ledgerRepository.saveAndFlush(ledger);
    }

    /***
     * 数据是否合法
     */
    private Model isVaild(SimpleRequest request, CustomRepository repository) {
        Model oldModel = (Model) repository.findOne((String) request.get("id"));
        if (oldModel == null) throw new RuntimeException("单据【" + request.get("id") + "】在系统中不存在。");
        if (oldModel.getVersion() != (int) request.get("version")) throw new RuntimeException("记录已更新或已删除，请重新提交！");
        return oldModel;
    }

}
